package com.iwhalecloud.citybrain.flow.platform.manager.application.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.task.TaskExecutionProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author: liyang
 * @date: 2021/12/17 21:41
 */
@Slf4j
@Configuration
@EnableConfigurationProperties(TaskExecutionProperties.class)
public class AsyncThreadPoolConfiguration implements AsyncConfigurer {

    @Autowired
    private TaskExecutionProperties properties;

    @Bean(name = "asyncEventThreadPoolTaskExecutor")
    public ThreadPoolTaskExecutor executor(){
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(properties.getPool().getCoreSize());
        taskExecutor.setMaxPoolSize(properties.getPool().getMaxSize());
        taskExecutor.setQueueCapacity(properties.getPool().getQueueCapacity());
        taskExecutor.setKeepAliveSeconds((int)properties.getPool().getKeepAlive().getSeconds());
        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        taskExecutor.setThreadNamePrefix("asyncEventThreadPool-");
        taskExecutor.initialize();
        return taskExecutor;
    }

    @Override
    public Executor getAsyncExecutor(){
        return executor();
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler(){
        return (ex,method,params) ->
            log.error("线程池执行任务发生未知错误，执行方法：{}",method.getName(),ex);
    }

}
